package com.wpen.unit.service.job.impl;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import com.wpen.unit.service.job.TaskInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wpen.unit.AppVariables;
import com.wpen.unit.core.cache.CacheDatas;
import com.wpen.unit.core.cache.CacheTaskJobDpdon;
import com.wpen.unit.cron.CronUtil;
import com.wpen.unit.cvt.job.TaskInfoCvt;
import com.wpen.unit.enums.AppMode;
import com.wpen.unit.enums.DependType;
import com.wpen.unit.enums.YN;
import com.wpen.unit.exception.BizException;
import com.wpen.unit.infra.mybatis.job.po.DependonPo;
import com.wpen.unit.infra.mybatis.job.po.JobInfoPo;
import com.wpen.unit.infra.mybatis.job.po.TaskInfoPo;
import com.wpen.unit.infra.repository.job.DependonRepository;
import com.wpen.unit.infra.repository.job.JobInfoRepository;
import com.wpen.unit.infra.repository.job.TaskInfoRepository;
import com.wpen.unit.utils.StringUtil;
import com.wpen.unit.web.dto.job.StatRequest;
import com.wpen.unit.web.dto.job.StatResponse;
import com.wpen.unit.web.dto.job.TaskInfoAddRequest;
import com.wpen.unit.web.dto.job.TaskInfoAddResponse;
import com.wpen.unit.web.dto.job.TaskInfoDelRequest;
import com.wpen.unit.web.dto.job.TaskInfoDelResponse;
import com.wpen.unit.web.dto.job.TaskInfoEnableRequest;
import com.wpen.unit.web.dto.job.TaskInfoEnableResponse;
import com.wpen.unit.web.dto.job.TaskInfoListRequest;
import com.wpen.unit.web.dto.job.TaskInfoListResponse;
import com.wpen.unit.web.dto.job.TaskInfoListRowsResponse;
import com.wpen.unit.web.dto.job.TaskInfoModRequest;
import com.wpen.unit.web.dto.job.TaskInfoModResponse;

@Service
public class TaskInfoServiceImpl implements TaskInfoService {

	@Autowired
	private TaskInfoRepository taskInfoRepository;
	@Autowired
	private DependonRepository dependonRepository;
	@Autowired
	private JobInfoRepository jobInfoRepository;
	@Autowired
	private CacheDatas cacheDatas;
	@Autowired
	private CacheTaskJobDpdon cacheTaskJobDpdon;

	@Override
	public TaskInfoListResponse queryListTaskInfo(TaskInfoListRequest taskInfoListRequest) {
		int index = taskInfoListRequest.getIndex();
		int size = taskInfoListRequest.getSize();
		// 数据库查询
		TaskInfoPo taskInfoPo = TaskInfoCvt.INSTANCE.queryListDto2Do(taskInfoListRequest);

		long total = taskInfoRepository.count(taskInfoPo);
		List<TaskInfoPo> taskInfoPoLists = taskInfoRepository.queryList(index, size, taskInfoPo);

		// 返回响应信息
		TaskInfoListResponse taskInfoListResponse = new TaskInfoListResponse();
		taskInfoListResponse.setTotal(total);
		taskInfoListResponse.setCount(0);
		if (taskInfoPoLists != null) {
			taskInfoListResponse.setCount(taskInfoPoLists.size());
			List<TaskInfoListRowsResponse> listRows = taskInfoListResponse.getRows();
			for (TaskInfoPo inTaskInfoPo : taskInfoPoLists) {
				TaskInfoListRowsResponse row = TaskInfoCvt.INSTANCE.queryListRowDo2Dto(inTaskInfoPo);
				listRows.add(row);
			}
			taskInfoListResponse.setRows(listRows);
		}

		return taskInfoListResponse;
	}

	@Override
	@Transactional
	public TaskInfoAddResponse addTaskInfo(TaskInfoAddRequest taskInfoAddRequest) {
		// 持久化操作
		TaskInfoPo taskInfoPo = TaskInfoCvt.INSTANCE.addDto2Do(taskInfoAddRequest);
		taskInfoPo.setEnabled(YN.No.value());
		taskInfoPo.setCreateTime(new Date());
		taskInfoPo.setVersion(1);
		// 测试cron是否正确
		if (!StringUtil.isEmpty(taskInfoAddRequest.getScheduleConf())) {
			CronUtil.getTime(taskInfoAddRequest.getScheduleConf(), new Date());
		}
		// 保存数据
		taskInfoRepository.insert(taskInfoPo);

		// 添加依赖关系，
		DependonPo taskDpdPo = new DependonPo();
		// B-批次，T-任务，J-任务作业
		taskDpdPo.setSelfType(DependType.Task.value());
		taskDpdPo.setBizCode(taskInfoPo.getBizCode());
		taskDpdPo.setBatchCode(taskInfoPo.getBatchCode());
		taskDpdPo.setTaskCode(taskInfoPo.getTaskCode());
		taskDpdPo.setJobCode(AppVariables.DEPENDON_PHD);
		taskDpdPo.setDpdonBizCode(taskInfoPo.getBizCode());
		taskDpdPo.setDpdonBatchCode(taskInfoPo.getBatchCode());
		taskDpdPo.setDpdonTaskCode(AppVariables.DEPENDON_PHD);
		taskDpdPo.setDpdonJobCode(AppVariables.DEPENDON_PHD);
		DependonPo dependonPoDb = dependonRepository.queryFirst(taskDpdPo);
		if (dependonPoDb == null) {
			taskDpdPo.setEnabled(YN.Yes.value());
			taskDpdPo.setCreateTime(new Date());
			dependonRepository.insert(taskDpdPo);
		}
		// 如果是常规的，直接添加作业任务
		if (AppMode.Normal.value().equals(taskInfoPo.getAppMode())) {
			JobInfoPo jobInfoPo = new JobInfoPo();
			jobInfoPo.setBizCode(taskInfoPo.getBizCode());
			jobInfoPo.setBatchCode(taskInfoPo.getBatchCode());
			jobInfoPo.setTaskCode(taskInfoPo.getTaskCode());
			jobInfoPo.setJobCode(taskInfoPo.getTaskCode() + "01");
			jobInfoPo.setJobName(taskInfoPo.getTaskName());
			jobInfoPo.setCreateTime(new Date());
			jobInfoPo.setEnabled(YN.Yes.value());
			jobInfoPo.setOrders(1);
			jobInfoPo.setFailIgnore(YN.No.value());
			jobInfoRepository.insert(jobInfoPo);

			// 添加依赖关系，
			DependonPo jobDpdPo = new DependonPo();
			// B-批次，T-任务，J-任务作业
			jobDpdPo.setSelfType(DependType.Job.value());
			jobDpdPo.setBizCode(taskInfoPo.getBizCode());
			jobDpdPo.setBatchCode(taskInfoPo.getBatchCode());
			jobDpdPo.setTaskCode(taskInfoPo.getTaskCode());
			jobDpdPo.setJobCode(taskInfoPo.getTaskCode() + "01");
			jobDpdPo.setDpdonBizCode(taskInfoPo.getBizCode());
			jobDpdPo.setDpdonBatchCode(taskInfoPo.getBatchCode());
			jobDpdPo.setDpdonTaskCode(taskInfoPo.getTaskCode());
			jobDpdPo.setDpdonJobCode(AppVariables.DEPENDON_PHD);
			DependonPo jobDpdPoDb = dependonRepository.queryFirst(jobDpdPo);
			if (jobDpdPoDb == null) {
				jobDpdPo.setEnabled(YN.Yes.value());
				jobDpdPo.setCreateTime(new Date());
				dependonRepository.insert(jobDpdPo);
			}
		}

		// 返回响应信息
		TaskInfoAddResponse taskInfoAddResponse = new TaskInfoAddResponse();
		return taskInfoAddResponse;
	}

	@Override
	public TaskInfoModResponse modTaskInfo(TaskInfoModRequest taskInfoModRequest) {
		// 持久化操作
		TaskInfoPo taskInfoPo = TaskInfoCvt.INSTANCE.modDto2Do(taskInfoModRequest);
		// 查询数据是否存在
		TaskInfoPo taskInfoPoDb = taskInfoRepository.queryById(taskInfoPo.getId());
		if (taskInfoPoDb == null) {
			throw new BizException("E00001", taskInfoModRequest.getId() + "");
		}
		// 测试cron是否正确
		if (!StringUtil.isEmpty(taskInfoModRequest.getScheduleConf())) {
			CronUtil.getTime(taskInfoModRequest.getScheduleConf(), new Date());
		}
		// 缓存清理
		cacheDatas.removeTaskInfoById(taskInfoPoDb.getId());
		// 更新数据
		taskInfoPo.setId(taskInfoPoDb.getId());
		taskInfoPo.setBizCode(taskInfoPoDb.getBizCode());
		taskInfoPo.setBatchCode(taskInfoPoDb.getBatchCode());
		taskInfoPo.setTaskCode(taskInfoPoDb.getTaskCode());
		taskInfoPo.setVersion(taskInfoPoDb.getVersion());
		taskInfoPo.setEnabled(taskInfoPoDb.getEnabled());
		taskInfoPo.setCreateTime(taskInfoPoDb.getCreateTime());
		// taskInfoPo.setTimeStamp(taskInfoPoDb.getTimeStamp());
		taskInfoRepository.updateByIdWithEmpty(taskInfoPo);
		// 缓存清理
		cacheDatas.removeTaskInfoById(taskInfoPoDb.getId());
		// 返回响应信息
		TaskInfoModResponse taskInfoModResponse = new TaskInfoModResponse();
		return taskInfoModResponse;
	}

	@Override
	public TaskInfoEnableResponse enableTaskInfo(TaskInfoEnableRequest taskInfoEnableRequest) {
		// 维护状态的启动/停止，同步维护2个表。
		Long id = taskInfoEnableRequest.getId();
		// 查询数据是否存在
		TaskInfoPo taskInfoPo = taskInfoRepository.queryById(id);
		if (taskInfoPo == null) {
			throw new BizException("E00001", id);
		}
		// 测试cron是否正确
		if (!StringUtil.isEmpty(taskInfoPo.getScheduleConf())) {
			CronUtil.getTime(taskInfoPo.getScheduleConf(), new Date());
		}
		// 缓存清理
		cacheDatas.removeTaskInfoById(taskInfoPo.getId());

		String toEnable = null;
		if (YN.Yes.value().equals(taskInfoPo.getEnabled())) {
			toEnable = YN.No.value();
		} else {
			toEnable = YN.Yes.value();
		}

		TaskInfoPo upTaskInfoPo = new TaskInfoPo();
		upTaskInfoPo.setId(taskInfoPo.getId());
		upTaskInfoPo.setVersion(taskInfoPo.getVersion());
		upTaskInfoPo.setEnabled(toEnable);
		taskInfoRepository.updateById(upTaskInfoPo);

		// 缓存清理
		cacheDatas.removeTaskInfoById(taskInfoPo.getId());

		TaskInfoEnableResponse response = new TaskInfoEnableResponse();
		response.setEnabled(toEnable);
		return response;
	}

	@Override
	@Transactional
	public TaskInfoDelResponse delTaskInfo(TaskInfoDelRequest taskInfoDelRequest) {
		// 持久化操作
		// 查询数据是否存在
		TaskInfoPo taskInfoPoDb = taskInfoRepository.queryById(taskInfoDelRequest.getId());
		if (taskInfoPoDb == null) {
			throw new BizException("E00001", taskInfoDelRequest.getId() + "");
		}
		String bizCode = taskInfoPoDb.getBizCode();
		String batchCode = taskInfoPoDb.getBatchCode();
		String taskCode = taskInfoPoDb.getTaskCode();
		// 删除数据
		boolean del = taskInfoRepository.deleteByIds(new Serializable[] { taskInfoDelRequest.getId() });
		if (del) {
			// 删除作业
			jobInfoRepository.deleteByCode(bizCode, batchCode, taskCode);
			// 清理依赖
			cacheTaskJobDpdon.removeDpds(bizCode, batchCode, taskCode, null);
			// 删除依赖父
			dependonRepository.deletePrtByCode(bizCode, batchCode, taskCode);
			// 删除依赖子
			dependonRepository.deleteSubByCode(bizCode, batchCode, taskCode);
		}
		// 缓存清理
		cacheDatas.removeTaskInfoById(taskInfoPoDb.getId());

		// 返回响应信息
		TaskInfoDelResponse taskInfoDelResponse = new TaskInfoDelResponse();
		return taskInfoDelResponse;
	}

	@Override
	public StatResponse statCountTask(StatRequest statRequest) {
		StatResponse statResponse = new StatResponse();
		TaskInfoPo taskInfoPo = new TaskInfoPo();
		long count = taskInfoRepository.count(taskInfoPo);
		statResponse.setCount(count);
		taskInfoPo.setEnabled(YN.Yes.value());
		long alive = taskInfoRepository.count(taskInfoPo);
		statResponse.setAlive(alive);
		return statResponse;
	}

}
